import { ArgumentMetadata, BadRequestException, PipeTransform } from '@nestjs/common';

import { 
  plainToInstance, // 将普通对象转换为类的实例
 } from 'class-transformer'

import {
  validate, // 验证对象
} from 'class-validator'

// 获取 DTO 类
import { CreateUserDto } from './create-user.dto'

/**
 * 基于类的架构验证
 */
export class ClassValidationPipe implements PipeTransform {
  async transform(value: any, metadata: ArgumentMetadata) {
    // 如果路由处理函数的参数没有类型 或 内置的类型 不需要验证
    if(!metadata.metatype || this.needValidate(metadata.metatype)) return value ;
    
    const instance = plainToInstance(metadata.metatype, value) // 将普通对象转换为类(metadata.metatype)的实例
    const errors = await validate(instance) // 验证对象
    if (errors.length > 0) { // 验证失败
      throw new BadRequestException('Validation failed') // 会被异常过滤器捕获并处理
    }
    return value;
  }
  
  /**
   * 内置的类型不需要验证
   */
  private needValidate(metatype: Function) {
    const types: Function[] = [String, Boolean, Number, Array, Object, Function]
    return types.includes(metatype)
  }
}
